package com.smartcommunity.service.dataImport;

import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.DataImport;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.ImportErrorMsg;
import com.smartcommunity.bean.entity.ImportField;
import com.smartcommunity.controller.DataImportBase;
import com.smartcommunity.dao.people.PeopleDao;
import com.smartcommunity.dao.village.HouseDao;
import com.smartcommunity.elasticsearch.people.PeopleEsApi;
import com.smartcommunity.entity.people.EsPeopleEntity;
import com.smartcommunity.entity.people.People;
import com.smartcommunity.entity.people.RealPeopleHouse;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.log.interceptor.Log;
import com.smartcommunity.service.dataImport.model.PeopleHouseExportModel;
import com.smartcommunity.service.village.VillageService;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;


import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component("peopleHouse")
public class PeopleHouse extends DataImportBase implements DataImport {

    @Autowired
    private HouseDao houseDao;

    @Autowired
    private PeopleDao peopleDao;

    @Autowired
    private VillageService villageService;

    @Autowired
    private PeopleEsApi peopleEsApi;

    /**
     * 模板类型
     */
    private String type = "人房关系";

    /**
     * 内容标题
     */
    private  String[] headerTitle = new String[]{"证件号码","楼栋编号","单元号","房间编号"};

    /**
     * 错误信息
     */
    private  String[] headerErrorMsg = new String[]{"不能为空或系统不存在","不能为空或系统不存在","不能为空或系统不存在","不能为空或系统不存在"};

    /**
     * key taskId,value progress
     */
    final int cacheSize = 100000;
    Map<String, Integer> progressTag = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
            return size() > cacheSize;
        }
    };

    @Override
    @Transactional
    @Log(info = "人房关系模板导入")
    public String importData(List list, String villageCode,String fileName, String taskId,HttpServletResponse response) throws IllegalArgumentException, BusinessException {
        progressTag.put(taskId,10);
        // 设置小区编码（必填）
        if (StringUtils.isBlank(villageCode)) {
            throw new IllegalArgumentException("小区编码为空！");
        }
        List<String> villageCodeList = new ArrayList<>();
        villageCodeList.add(villageCode);
        // 初始化导入模板信息
        ImportErrorMsg msg = getFiledInfo(type,headerTitle,headerErrorMsg);

        // 字段校验信息
        List<ImportField> fieldList = msg.getFieldList();

        // 根据小区编号获取所有的楼栋  单元号和房屋编号
        Map<String, Map<String, List<String>>> allHouses = villageService.getAllHousesByVillageCode(villageCode);

        // 根据小区编号获取所有的人员身份证号码
        Map<String, String> param = new HashedMap();
        param.put("villageCode",villageCode);
        List<People> peopleList = peopleDao.listPeoplesByParam(param);
        List<String> peopleNos = peopleList.stream().map(item->item.getCredentialNo()).collect(Collectors.toList());

        List<Object[]> dataList = (List<Object[]>) list;
        //存储错误信息
        List<PeopleHouseExportModel> dataListCopy = new ArrayList<>();
        List<RealPeopleHouse> peopleHouseList = new ArrayList<>();
        List<People> esPeopleList = new ArrayList<>();
        int size = dataList.size();
        int errorCount = 0;
        for (int i = 0; i < size; i++) {
            boolean isError = false;
            Object[] objects = dataList.get(i);
            int currentRow = Constant.START_ROW + i;

            RealPeopleHouse peopleHouse = new RealPeopleHouse();
            peopleHouse.setVillageCode(villageCode);
            People people = new People();

            StringBuffer errorMessages = new StringBuffer();
            //身份证号码（必填）
            String credentialNo = (String) objects[0];
            if (StringUtils.isBlank(credentialNo) || !peopleNos.contains(credentialNo)) {
                //添加错误的行数
                String errorMsg = appendErrorMsg(fieldList.get(0).getTitle(), credentialNo, fieldList.get(0).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                peopleHouse.setCredentialNo(credentialNo);
                people.setCredentialNo(credentialNo);
            }

            //楼栋编号（必填）
            String buildingNo = (String) objects[1];
            if (StringUtils.isBlank(buildingNo) || !allHouses.containsKey(buildingNo)) {
                //添加错误的行数
                String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), buildingNo, fieldList.get(1).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                peopleHouse.setBuildingNo(buildingNo);
            }

            //设置单元号（必填）
            String unitNo = (String) objects[2];
            if(StringUtils.isNotBlank(peopleHouse.getBuildingNo())) {
	            if (StringUtils.isBlank(unitNo) || !allHouses.get(peopleHouse.getBuildingNo()).containsKey(unitNo)) {
	                //添加错误的行数
	                String errorMsg = appendErrorMsg(fieldList.get(2).getTitle(), unitNo, fieldList.get(2).getErrorMsg());
	                errorMessages.append(errorMsg);
	                isError = true;
	            }else{
	                peopleHouse.setUnitNo(unitNo);
	            }
            }

            // 设置房间号（必填）
            String houseNo = (String) objects[3];
            if(StringUtils.isNotBlank(peopleHouse.getBuildingNo()) && StringUtils.isNotBlank(peopleHouse.getUnitNo())) {
            	List<String> houseNos = allHouses.get(peopleHouse.getBuildingNo()).get(peopleHouse.getUnitNo());
	            if (StringUtils.isBlank(houseNo) || !houseNos.contains(houseNo)) {
	                //添加错误的行数
	                String errorMsg = appendErrorMsg(fieldList.get(3).getTitle(), houseNo, fieldList.get(3).getErrorMsg());
	                errorMessages.append(errorMsg);
	                isError = true;
	            }else{
	                peopleHouse.setHouseNo(houseNo);
	            }
            }

            //判断当前行是否有错误
            if(isError){
                errorCount++;
                PeopleHouseExportModel exportModel = new PeopleHouseExportModel();
                exportModel.setCredentialNo(credentialNo);
                exportModel.setBuildingNo(buildingNo);
                exportModel.setUnitNo(unitNo);
                exportModel.setHouseNo(houseNo);
                exportModel.setErrorMsg(errorMessages.toString());
                dataListCopy.add(exportModel);
            }else{
                peopleHouse.setHouseNo(houseNo);
                peopleHouseList.add(peopleHouse);
                //构建es中的实口信息
                List<RealPeopleHouse> detailAddress = new ArrayList<>();
                detailAddress.add(peopleHouse);
                people.setDetailAddress(detailAddress);
                esPeopleList.add(people);
            }
        }

        //入库
        try {
            progressTag.put(taskId, 20);
            //处理掉相同小区没有楼栋、单元号、房间号的数据
            houseDao.deleteNoBuildUnitHouseNo(peopleHouseList);
            houseDao.insertPeopleHouse(peopleHouseList);
            progressTag.put(taskId, 60);
            //ES入库
            List<String> credentialNos = new ArrayList<String>();
            Map<String, People> peopleMap = new HashMap<String, People>();
            for(People people:esPeopleList) {
            	if(StringUtils.isNotEmpty(people.getCredentialNo())) {
            		credentialNos.add(people.getCredentialNo());
            		if(peopleMap.containsKey(people.getCredentialNo())) {
            			people.getDetailAddress().addAll(peopleMap.get(people.getCredentialNo()).getDetailAddress());
            		}
            		peopleMap.put(people.getCredentialNo(), people);
            	}
            }
            if (CollectionUtils.isNotEmpty(credentialNos)) {
                List<EsPeopleEntity> esPeopleEntitys = peopleEsApi.getDataByIds(credentialNos);
                if (CollectionUtils.isNotEmpty(esPeopleEntitys)) {
                    for (EsPeopleEntity esPeople : esPeopleEntitys) {
                        if (peopleMap.containsKey(esPeople.getCredentialNo())) {

                            //老的房屋数据，居住地址，可能多小区
                            List<RealPeopleHouse> newDetailAddressList = peopleMap.get(esPeople.getCredentialNo()).getDetailAddress();
                            Map<String, RealPeopleHouse> map = new HashedMap();
                            for (RealPeopleHouse newpeopleHouse : newDetailAddressList) {
                                map.put(newpeopleHouse.getVillageCode(), newpeopleHouse);
                            }
                            //新导入的数据
                            List<RealPeopleHouse> oldDetailAddressList = esPeople.getDetailAddress();
                            for (RealPeopleHouse oldPeopleHouse : oldDetailAddressList) {
                                if (map.containsKey(oldPeopleHouse.getVillageCode())) {
                                    RealPeopleHouse newpeopleHouse = map.get(oldPeopleHouse.getVillageCode());

                                    //处理掉相同小区没有楼栋、单元号、房间号的数据
                                    if ((newpeopleHouse.getBuildingNo().equals(oldPeopleHouse.getBuildingNo())
                                            && newpeopleHouse.getUnitNo().equals(oldPeopleHouse.getUnitNo())
                                            && newpeopleHouse.getHouseNo().equals(oldPeopleHouse.getHouseNo()))
                                            ||
                                            (StringUtils.isBlank(oldPeopleHouse.getBuildingNo())
                                            && StringUtils.isBlank(oldPeopleHouse.getUnitNo())
                                            && StringUtils.isBlank(oldPeopleHouse.getHouseNo()))) {
                                        continue;
                                    }else {
                                        newDetailAddressList.add(oldPeopleHouse);
                                    }
                                }
                            }
                            wrapPeopleHouseList(esPeople, newDetailAddressList);
                        }
                    }
                    progressTag.put(taskId, 80);
                    peopleEsApi.batchSaveOrUpdateEsPeople(esPeopleEntitys, false);
                }
            }
            //正常的数据需要导入进去，错误的数据返回到Excel
            if (errorCount>0) {
                String errorFileName = exportExcelToLocal(taskId,fileName,headerTitle,dataListCopy);
                progressTag.put(taskId,100);
                return errorFileName;
            }
        } catch (Exception e) {
            log.error("人房关系导入失败，保存数据库异常！", e);
            throw new BusinessException(ExceptionCode.HOUSE_SQL_EXCEPTION_CODE, "人房关系导入失败，保存数据库异常！");
        }
        log.info("人房关系导入完成");
        progressTag.put(taskId, 100);
        return "";
    }

    @Override
    public int getImportDataProgress(String taskId) {
        return progressTag.get(taskId) == null ? 0 : progressTag.get(taskId);
    }

    /**
     * 包装人房关系实体
     */
	private void wrapPeopleHouseList(EsPeopleEntity people, List<RealPeopleHouse> itemList) {
		List<RealPeopleHouse> houseList = new ArrayList<RealPeopleHouse>();
		if(CollectionUtils.isNotEmpty(itemList)) {
			itemList.forEach(item->{
				item.setDetailAddress(item.concatDetailAddress());
				houseList.add(item);
			});
		}
		people.setDetailAddress(houseList);
	}
}
